/* SPDX-License-Identifier: GPL-2.0 */
/*
 * initial boot stuff.. At this point, the bootloader has already
 * switched into HMcode, and loaded us at the correct address
 * (START_ADDR).  So there isn't much left for us to do: just set up
 * the kernel global pointer and jump to the kernel entry-point.
 */

#include <linux/init.h>
#include <asm/asm-offsets.h>
#include <asm/hmcall.h>
#include <asm/setup.h>

__HEAD
	.globl _stext
	.set noreorder
	.globl __start
	.ent __start
_stext:
__start:
	.prologue 0
	br	$27, 1f
1:	ldgp	$29, 0($27)
	/* We need to get current_task_info loaded up...  */
	ldi	$8, init_thread_union
	/* ... and find our stack ... */
	ldi	$30, 0x4000 - PT_REGS_SIZE($8)
	/* ... and then we can clear bss data.  */
	ldi	$2, __bss_start
	ldi	$3, __bss_stop
	/* 8 bytes alignment */
1:	and	$2, 0x7, $1	# align check
	bne	$1, 3f
2:	subl	$3, $2, $1	# align clear
	ble	$1, 4f
	subl	$1, 0x8, $1
	ble	$1, 3f
	stl	$31, 0($2)
	addl	$2, 8, $2
	br	$31, 2b
3:	stb	$31, 0($2)	# non align clear
	addl	$2, 1, $2
	subl	$3, $2, $1
	bgt	$1, 1b
4:# finish clear
#ifdef CONFIG_RELOCATABLE
	ldi	$30, -8($30)
	stl	$29, 0($30)
	/* Copy kernel and apply the relocations */
	call	$26, relocate_kernel
	ldl	$29, 0($30)
	addl	$29, $0, $29
	/* Repoint the sp into the new kernel image */
	ldi	$30, 0x4000 - PT_REGS_SIZE($8)
#endif
	/* ... and then we can start the kernel.  */
	call	$26, sw64_start_kernel
	sys_call HMC_halt
	.end __start

#ifdef CONFIG_SMP
	.align 3
	.globl __smp_callin
	.ent __smp_callin
	/* On entry here the PCB of the idle task for this processor
	 * has been loaded.  We've arranged for the tilde_pcb[x] for
	 * this process to contain the PCBB of the target idle task.
	 */
__smp_callin:
	.prologue 1
	br	$27, 2f		# we copy this from above "br $27 1f"
2:	ldgp	$29, 0($27)	# First order of business, load the GP.

	subl	$31, 2, $16
	sys_call HMC_tbi

	sys_call HMC_whami	# Get hard cid

	sll	$0, 2, $0
	ldi	$1, __rcid_to_cpu
	addl	$1, $0, $1
	ldw	$0, 0($1)	# Get logical cpu number

	sll	$0, 3, $0
	ldi	$1, tidle_pcb
	addl	$1, $0, $1
	ldl	$16, 0($1)	# Get PCBB of idle thread

	sys_call HMC_swpctx
	ldi	$8, 0x3fff	# Find "current".
	bic	$30, $8, $8

	call	$26, smp_callin
	sys_call HMC_halt
	.end __smp_callin
#endif /* CONFIG_SMP */
	#
	# It is handy, on occasion, to make halt actually just loop.
	# Putting it here means we dont have to recompile the whole
	# kernel.
	#

	.align 3
	.globl halt
	.ent halt
halt:
	.prologue 0
	sys_call HMC_halt
	.end halt
